// OsgPlotter.cpp - MARIN MSG Anneke Sicherer-Roetman 200xyyzz

// LIN_WACU

#include <osg/ShapeDrawable>
#include "OsgViewer.h"
#include "OsgPlotter.h"

#define WIDTH  800
#define HEIGHT 600
#define SCALE 1


/// constructor
OsgPlotter::OsgPlotter(int xmin,                   ///< lower left of field
                       int ymin,                   ///< lower left of field
                       int xmax,                   ///< upper right of field
                       int ymax,                   ///< upper right of field
                       float dx1,                  ///< horizontal point interval
                       float dx2,                  ///< vertical point interval
                       const Array2D<float> &plot, ///< array to read heightvalues from
                       const std::string &caption) ///< initial text to display
    : base(xmin, ymin, xmax, ymax, plot, caption)
    , m_pViewer(new osgviewer::OsgViewer(caption/*, (dx1 + dx2) / 2.0*/))
{
    // add heightfield to viewer
    m_pViewer->addDynamicSurface("waves", "0.7;0.92;1.0", &m_data, xmin, ymin, xmax, ymax, dx1, dx2);

    // set attributes of textbox
    m_pViewer->setCaptionAttributes(osg::Vec3(10, 10, 0), 48, "white");

    // sets viewpoint
    m_pViewer->setViewingDistanceFactors(osg::Vec3d(0.6, 1.1, 1.0));

    // start viewer
    m_pViewer->start();
}

   
/// destructor
OsgPlotter::~OsgPlotter()
{
    delete m_pViewer;
}


/// redraws all windows
void OsgPlotter::plot()
{
    m_pViewer->plot();
    m_pViewer->setCaption(m_caption);
}


/// keeps viewer running at end of simulation
void OsgPlotter::run()
{
    m_pViewer->run();
}


/// sets text to display at bottom left
void OsgPlotter::setCaption(const std::string& caption)
{
    m_pViewer->setCaption(caption);
}


/// sets viewpoint in z axis
void OsgPlotter::setZview()
{
    m_pViewer->setEye('z');
}


/// scales along z axis
void OsgPlotter::setZscale(float factor)
{
    m_pViewer->setScale('z', factor);
}


/// sets viewing distance
void OsgPlotter::setDistance(float distance) ///< viewing distance
{
    m_pViewer->setXyzHomeDistance(distance);
}


/// defines handler for clicking left
void OsgPlotter::setLeftClickHandler(osgviewer::ClickHandler handler)
{
    m_pViewer->setLeftClickHandler(handler);
}


/// defines handler for clicking right
void OsgPlotter::setRightClickHandler(osgviewer::ClickHandler handler)
{
    m_pViewer->setRightClickHandler(handler);
}


/// adds object to drawlist
void OsgPlotter::addObject(const std::string &name, const std::string &type, const std::string &color,
                           float diameter, float x1, float y1, float z1, float x2, float y2, float z2)
{
    m_pViewer->addObject(name, type, color, diameter, osg::Vec3d(x1, y1, z1), osg::Vec3d(x2, y2, z2));
}


/// moves existing object
void OsgPlotter::moveObject(const std::string &name, float x, float y, float z)
{
    m_pViewer->moveObject(name, osg::Vec3d(x, y, z));
}


/// rotates existing object
void OsgPlotter::rotateObject(const std::string &name, float x, float y, float z)
{
    m_pViewer->rotateObject(name, osg::Vec3d(x, y, z));
}


/// removes object from drawlist
bool OsgPlotter::removeObject(const std::string &name)
{
    return m_pViewer->removeObject(name);
}


/// removes object from drawlist
void OsgPlotter::removeAllObjects()
{
    m_pViewer->removeAllObjects();
}

void OsgPlotter::addAxes(const osg::Vec3 axes, float length, float ticks)
{
    m_pViewer->addAxes(axes, length, ticks);
}

void OsgPlotter::addPanelRoot(const std::string &name) ///< name of object (used as index)
{
    m_pViewer->addPanelRoot(name);
}


//----------------------------------------------------------------------------
// function OsgViewer::addPanel
//----------------------------------------------------------------------------
/// adds panel to already present panel root
//----------------------------------------------------------------------------
void OsgPlotter::addPanel(const std::string &name,                 ///< name of panel root
                          const std::string &color,                ///< color name or "r;g;b"
                          const std::vector<mml::Vector3d>& vertices, ///< corner points
                          const mml::Vector3d& normal)                ///< normal on panel
{
    osg::Vec3 n(normal(0), normal(1), normal(2));
    std::vector<osg::Vec3> v;
    for (unsigned int i = 0; i < vertices.size(); ++i)
    {
        const mml::Vector3d& vv = vertices[i];
        v.push_back(osg::Vec3(vv(0), vv(1), vv(2)));
    }
    m_pViewer->addPanel(name, color, v, n);
}


void OsgPlotter::toggleScreenCast()
{
    m_pViewer->toggleScreenCast();
}


void OsgPlotter::toggleLightDirection()
{
    m_pViewer->toggleLightDirection();
}
